package com.pignest.hotel.system.filter;

import java.io.IOException;
import java.util.HashSet;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.web.util.WebUtils;

import com.pignest.framework.util.Utils;
import com.pignest.hotel.beans.User;
import com.pignest.hotel.beans.global.ClientSession;
import com.pignest.hotel.spring.Services;
import com.pignest.hotel.system.AuthenticatorHolder;
import com.pignest.hotel.system.Hotel;
import com.pignest.hotel.system.Key;
import com.pignest.hotel.system.P;
import com.pignest.hotel.system.Permission;

public class AuthenticateFilter implements Filter {
	
	private static final String LOGIN_URL = "/modules/global/login.jsp";
	private static final String FORBIDDEN_URL = "/modules/global/forbidden.jsp";
	private static final String AUDIT_URL = "/modules/global/audit.jsp";
	
	private HashSet<String> unfilteredTypes;
	private String unfilteredURIs;
//	private String loginURL;
	
//	private ServletContext servletContext;
	

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain chain) throws IOException, ServletException {
		
		if (Hotel.TEST) {
			chain.doFilter(sRequest, sResponse);
			return;
		}
		HttpServletRequest request = ((HttpServletRequest) sRequest);
		HttpServletResponse response = (HttpServletResponse) sResponse;
		if (Services.getGlobalService().isAuditing()) {
			response.sendRedirect(AUDIT_URL);
			return;
		}
		String requestURI = request.getRequestURI();
		int len = request.getContextPath().length();
		if (len > 1) {
			requestURI = requestURI.substring(len);
		}
		String ext = Utils.getExtention(requestURI);
		if (unfilteredTypes.contains(ext)) {
			chain.doFilter(request, sResponse);
			return;
		}

		if (requestURI.matches(unfilteredURIs)) {
			chain.doFilter(request, sResponse);
			return;
		}
		
		//其它网页都需要登录, 并且可能需要相应的权限
		System.out.println(requestURI);
		doFilter(request, response, chain, requestURI);
	}
	
	private boolean checkPermission(User user, String uri) {
		String[] permissions = P.get().getPermissions(uri);
		if (permissions == null || permissions.length == 0) {
			return true;
		}
		return Permission.alow(permissions, user);
	}
	
	private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain, String uri)
			throws IOException, ServletException {
		
		ClientSession cs = (ClientSession) request.getSession(true).getAttribute(Key.CLIENT_SESSION);

		if ((cs != null && cs.isLogined())) {
			AuthenticatorHolder.setClientSession(cs);
			if (checkPermission(cs.getUser(), uri)) {
				chain.doFilter(request, response);
				return;
			}
			response.sendRedirect(request.getContextPath() + FORBIDDEN_URL);
			return;
		}
		
		//登录
		Cookie cookie = WebUtils.getCookie(request, Key.WORK_NUMBER);
		Cookie cookie2 = WebUtils.getCookie(request, Key.PASSWORD);

		if (cookie != null && cookie.getValue() != null) {
			String workNo = cookie.getValue();
			String password = null;
			if (cookie2 != null) {
				password = cookie2.getValue();
				if (password == null) {
					password = "";
				}
			}
			if (StringUtils.isNotEmpty(workNo) && !"null".equals(workNo)) {
				try {
					// LoginAction.authenticate(hrequest,hresponse,servletContext,username,password,true);
					if (Hotel.login(request, response, workNo, password, false)) {
						if (checkPermission(Hotel.getCurrentUser(), uri)) {
							chain.doFilter(request, response);
							return;
						} else {
							response.sendRedirect(request.getContextPath() + FORBIDDEN_URL);
							return;
						}
					}
				} catch (Throwable t) {
				}
			}
		}
		request.getSession().setAttribute("requestURI", request.getRequestURI());
		response.sendRedirect(request.getContextPath() + LOGIN_URL);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
//		servletContext = config.getServletContext();
//		loginURL = config.getInitParameter("loginURL").trim();
		unfilteredURIs = jointString(config.getInitParameter("unfilteredURIs"));
		
		unfilteredTypes = new HashSet<String>();
		String resourceTypes = config.getInitParameter("resourceTypes").trim().toLowerCase();
		String[] ss = StringUtils.split(resourceTypes, "#");
		for (int i = 0; i < ss.length; i++) {
			unfilteredTypes.add(ss[i]);
		}
	}

	protected String jointString(String str) {
		StringBuffer buf = new StringBuffer();
		for (StringTokenizer st = new StringTokenizer(str != null ? str : "",
				"\n", false); st.hasMoreTokens(); buf.append(st.nextToken()
				.trim()))
			;
		return buf.toString();
	}

}
